/**
 * ${domainObjectName} Vue3组件
 * 
 * @author Auto Generated
 */
<template>
  <div class="${domainObjectName?uncap_first}-container">
    <!-- 搜索表单 -->
    <div class="search-container">
      <a-form layout="inline" :model="searchForm" @finish="handleSearch">
        <a-form-item label="${domainObjectName}名称" name="name">
          <a-input v-model:value="searchForm.name" placeholder="请输入${domainObjectName}名称" allow-clear />
        </a-form-item>
        
<#list fields as field>
  <#if field.searchable?? && field.searchable>
        <a-form-item label="${field.comment}" name="${field.name}">
    <#if field.javaType == "String">
          <a-input v-model:value="searchForm.${field.name}" placeholder="请输入${field.comment}" allow-clear />
    <#elseif field.javaType == "Date" || field.javaType == "LocalDate" || field.javaType == "LocalDateTime">
          <a-range-picker v-model:value="searchForm.${field.name}Range" />
    <#elseif field.javaType == "Integer" || field.javaType == "Long" || field.javaType == "Double" || field.javaType == "BigDecimal">
          <a-input-number v-model:value="searchForm.${field.name}" placeholder="请输入${field.comment}" style="width: 100%" />
    <#elseif field.javaType == "Boolean">
          <a-select v-model:value="searchForm.${field.name}" placeholder="请选择" allow-clear>
            <a-select-option :value="true">是</a-select-option>
            <a-select-option :value="false">否</a-select-option>
          </a-select>
    <#else>
          <a-input v-model:value="searchForm.${field.name}" placeholder="请输入${field.comment}" allow-clear />
    </#if>
        </a-form-item>
  </#if>
</#list>
        
        <a-form-item>
          <a-space>
            <a-button type="primary" html-type="submit">
              <template #icon><search-outlined /></template>
              查询
            </a-button>
            <a-button @click="resetSearch">
              <template #icon><redo-outlined /></template>
              重置
            </a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </div>
    
    <!-- 操作按钮 -->
    <div class="operation-container">
      <a-space>
        <a-button type="primary" @click="openModal()">
          <template #icon><plus-outlined /></template>
          新增${domainObjectName}
        </a-button>
        <a-button @click="handleRefresh">
          <template #icon><reload-outlined /></template>
          刷新
        </a-button>
<#if specialRequirements?? && specialRequirements?contains("导出")>
        <a-button @click="handleExport">
          <template #icon><download-outlined /></template>
          导出
        </a-button>
</#if>
<#if specialRequirements?? && specialRequirements?contains("导入")>
        <a-upload
          :customRequest="handleImport"
          :showUploadList="false"
          accept=".xlsx,.xls"
        >
          <a-button>
            <template #icon><upload-outlined /></template>
            导入
          </a-button>
        </a-upload>
</#if>
        <a-button danger :disabled="!hasSelected" @click="handleBatchDelete">
          <template #icon><delete-outlined /></template>
          批量删除
        </a-button>
      </a-space>
    </div>
    
    <!-- 数据表格 -->
    <a-table
      :columns="columns"
      :data-source="tableData"
      :pagination="pagination"
      :loading="loading"
      :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
      row-key="id"
      @change="handleTableChange"
    >
      <!-- 状态列 -->
      <template #bodyCell="{ column, record }">
<#list fields as field>
  <#if field.name == "status">
        <template v-if="column.dataIndex === 'status'">
          <a-tag :color="getStatusColor(record.status)">
            {{ getStatusText(record.status) }}
          </a-tag>
        </template>
  </#if>
</#list>
        
        <!-- 操作列 -->
        <template v-if="column.dataIndex === 'operation'">
          <a-space>
            <a @click="openModal(record)">查看</a>
            <a-divider type="vertical" />
            <a @click="openModal(record, 'edit')">编辑</a>
            <a-divider type="vertical" />
            <a-popconfirm
              title="确定要删除该${domainObjectName}吗?"
              ok-text="确定"
              cancel-text="取消"
              @confirm="handleDelete(record)"
            >
              <a class="text-danger">删除</a>
            </a-popconfirm>
          </a-space>
        </template>
      </template>
    </a-table>
    
    <!-- 表单弹窗 -->
    <a-modal
      :title="modalTitle"
      :visible="modalVisible"
      :confirm-loading="modalLoading"
      @cancel="closeModal"
      :maskClosable="false"
      width="700px"
    >
      <a-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
<#list fields as field>
  <#if field.name != "id" && field.name != "createdTime" && field.name != "updatedTime" && field.name != "createdBy" && field.name != "updatedBy" && field.name != "isDeleted">
        <a-form-item label="${field.comment}" name="${field.name}"<#if field.required?? && field.required> required</#if>>
    <#if field.javaType == "String">
      <#if field.length?? && field.length gt 200>
          <a-textarea v-model:value="formData.${field.name}" placeholder="请输入${field.comment}" :rows="4" <#if viewMode>:disabled="viewMode"</#if> />
      <#else>
          <a-input v-model:value="formData.${field.name}" placeholder="请输入${field.comment}" <#if viewMode>:disabled="viewMode"</#if> />
      </#if>
    <#elseif field.javaType == "Date" || field.javaType == "LocalDate">
          <a-date-picker v-model:value="formData.${field.name}" style="width: 100%" <#if viewMode>:disabled="viewMode"</#if> />
    <#elseif field.javaType == "LocalDateTime">
          <a-date-picker v-model:value="formData.${field.name}" show-time style="width: 100%" <#if viewMode>:disabled="viewMode"</#if> />
    <#elseif field.javaType == "Integer" || field.javaType == "Long">
          <a-input-number v-model:value="formData.${field.name}" placeholder="请输入${field.comment}" style="width: 100%" <#if viewMode>:disabled="viewMode"</#if> />
    <#elseif field.javaType == "Double" || field.javaType == "BigDecimal">
          <a-input-number v-model:value="formData.${field.name}" placeholder="请输入${field.comment}" style="width: 100%" :precision="2" <#if viewMode>:disabled="viewMode"</#if> />
    <#elseif field.javaType == "Boolean">
          <a-switch v-model:checked="formData.${field.name}" <#if viewMode>:disabled="viewMode"</#if> />
    <#elseif field.name == "status">
          <a-select v-model:value="formData.${field.name}" placeholder="请选择状态" <#if viewMode>:disabled="viewMode"</#if>>
            <a-select-option :value="0">禁用</a-select-option>
            <a-select-option :value="1">启用</a-select-option>
          </a-select>
    <#else>
          <a-input v-model:value="formData.${field.name}" placeholder="请输入${field.comment}" <#if viewMode>:disabled="viewMode"</#if> />
    </#if>
        </a-form-item>
  </#if>
</#list>
      </a-form>
      
      <template #footer>
        <a-space>
          <a-button @click="closeModal">取消</a-button>
          <a-button v-if="!viewMode" type="primary" :loading="modalLoading" @click="handleSubmit">确定</a-button>
        </a-space>
      </template>
    </a-modal>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { 
  SearchOutlined, RedoOutlined, PlusOutlined, ReloadOutlined, 
  DownloadOutlined, UploadOutlined, DeleteOutlined 
} from '@ant-design/icons-vue';
import { 
  get${domainObjectName}List,
  get${domainObjectName}Detail,
  create${domainObjectName},
  update${domainObjectName},
  delete${domainObjectName},
  batchDelete${domainObjectName},
<#if specialRequirements?? && specialRequirements?contains("导出")>
  export${domainObjectName}Excel,
</#if>
<#if specialRequirements?? && specialRequirements?contains("导入")>
  import${domainObjectName}Excel,
</#if>
} from '@/api/${domainObjectName?lower_case}';

// 查询表单
const searchForm = reactive({
  name: '',
<#list fields as field>
  <#if field.searchable?? && field.searchable>
    <#if field.javaType == "Date" || field.javaType == "LocalDate" || field.javaType == "LocalDateTime">
  ${field.name}Range: [],
    <#else>
  ${field.name}: undefined,
    </#if>
  </#if>
</#list>
});

// 表格数据
const tableData = ref([]);
const loading = ref(false);
const pagination = reactive({
  current: 1,
  pageSize: 10,
  total: 0,
  showTotal: (total) => `共 ${total} 条`,
  showSizeChanger: true,
  pageSizeOptions: ['10', '20', '50', '100'],
});

// 表格列定义
const columns = [
<#list fields as field>
  <#if field.name != "isDeleted">
  {
    title: '${field.comment}',
    dataIndex: '${field.name}',
    <#if field.name == "id">width: 80,</#if>
    <#if field.name == "status">
    customRender: ({ text }) => {
      return {
        props: {
          color: text === 1 ? 'success' : 'error',
        },
        children: text === 1 ? '启用' : '禁用',
      };
    },
    </#if>
  },
  </#if>
</#list>
  {
    title: '操作',
    dataIndex: 'operation',
    fixed: 'right',
    width: 180,
  },
];

// 多选功能
const selectedRowKeys = ref([]);
const hasSelected = computed(() => selectedRowKeys.value.length > 0);
const onSelectChange = (keys) => {
  selectedRowKeys.value = keys;
};

// 表单弹窗
const modalVisible = ref(false);
const modalLoading = ref(false);
const formMode = ref('add'); // 'add', 'edit', 'view'
const viewMode = computed(() => formMode.value === 'view');
const modalTitle = computed(() => {
  const baseTitle = '${domainObjectName}';
  if (formMode.value === 'add') return `新增${baseTitle}`;
  if (formMode.value === 'edit') return `编辑${baseTitle}`;
  return `查看${baseTitle}`;
});

// 表单数据
const formRef = ref(null);
const formData = reactive({
  id: null,
<#list fields as field>
  <#if field.name != "id" && field.name != "createdTime" && field.name != "updatedTime" && field.name != "createdBy" && field.name != "updatedBy" && field.name != "isDeleted">
  ${field.name}: <#if field.javaType == "String">''<#elseif field.javaType == "Boolean">false<#else>undefined</#if>,
  </#if>
</#list>
});

// 表单校验规则
const formRules = {
<#list fields as field>
  <#if field.required?? && field.required && field.name != "id" && field.name != "createdTime" && field.name != "updatedTime" && field.name != "createdBy" && field.name != "updatedBy" && field.name != "isDeleted">
  ${field.name}: [
    { required: true, message: '请<#if field.javaType == "String">输入<#else>选择</#if>${field.comment}', trigger: '<#if field.javaType == "String">blur<#else>change</#if>' },
    <#if field.javaType == "String" && field.length??>
    { max: ${field.length}, message: '${field.comment}不能超过${field.length}个字符', trigger: 'blur' },
    </#if>
  ],
  </#if>
</#list>
};

// 获取表格数据
const getTableData = async () => {
  loading.value = true;
  try {
    const params = {
      pageNum: pagination.current,
      pageSize: pagination.pageSize,
      ...prepareSearchParams(),
    };
    const res = await get${domainObjectName}List(params);
    if (res.success) {
      tableData.value = res.data.list;
      pagination.total = res.data.total;
    } else {
      message.error(res.message || '获取数据失败');
    }
  } catch (error) {
    console.error('获取数据出错:', error);
    message.error('获取数据失败');
  } finally {
    loading.value = false;
  }
};

// 处理搜索参数
const prepareSearchParams = () => {
  const params = { ...searchForm };
<#list fields as field>
  <#if field.searchable?? && field.searchable && (field.javaType == "Date" || field.javaType == "LocalDate" || field.javaType == "LocalDateTime")>
  if (params.${field.name}Range && params.${field.name}Range.length === 2) {
    params.${field.name}Start = params.${field.name}Range[0].format('YYYY-MM-DD HH:mm:ss');
    params.${field.name}End = params.${field.name}Range[1].format('YYYY-MM-DD HH:mm:ss');
    delete params.${field.name}Range;
  }
  </#if>
</#list>
  return params;
};

// 查询
const handleSearch = () => {
  pagination.current = 1;
  getTableData();
};

// 重置查询
const resetSearch = () => {
  // 重置查询表单
  Object.keys(searchForm).forEach(key => {
    searchForm[key] = Array.isArray(searchForm[key]) ? [] : undefined;
  });
  handleSearch();
};

// 刷新
const handleRefresh = () => {
  getTableData();
};

// 表格分页、排序、筛选变化
const handleTableChange = (pag) => {
  pagination.current = pag.current;
  pagination.pageSize = pag.pageSize;
  getTableData();
};

// 打开模态框
const openModal = (record, mode = 'view') => {
  resetForm();
  formMode.value = mode;
  
  if (record) {
    // 编辑或查看时加载详情
    loadDetail(record.id);
  } else {
    // 新增时直接打开空表单
    modalVisible.value = true;
  }
};

// 加载详情
const loadDetail = async (id) => {
  try {
    modalLoading.value = true;
    const res = await get${domainObjectName}Detail(id);
    if (res.success) {
      Object.assign(formData, res.data);
      modalVisible.value = true;
    } else {
      message.error(res.message || '获取详情失败');
    }
  } catch (error) {
    console.error('获取详情出错:', error);
    message.error('获取详情失败');
  } finally {
    modalLoading.value = false;
  }
};

// 重置表单
const resetForm = () => {
  Object.keys(formData).forEach(key => {
    formData[key] = key === 'id' ? null : (typeof formData[key] === 'boolean' ? false : (typeof formData[key] === 'string' ? '' : undefined));
  });
  formRef.value?.resetFields();
};

// 关闭模态框
const closeModal = () => {
  modalVisible.value = false;
  setTimeout(() => {
    resetForm();
  }, 200);
};

// 提交表单
const handleSubmit = async () => {
  try {
    await formRef.value.validate();
    modalLoading.value = true;
    
    const apiMethod = formData.id ? update${domainObjectName} : create${domainObjectName};
    const res = await apiMethod(formData);
    
    if (res.success) {
      message.success(formData.id ? '更新成功' : '创建成功');
      closeModal();
      getTableData();
    } else {
      message.error(res.message || (formData.id ? '更新失败' : '创建失败'));
    }
  } catch (error) {
    console.error('表单提交出错:', error);
  } finally {
    modalLoading.value = false;
  }
};

// 删除
const handleDelete = async (record) => {
  try {
    const res = await delete${domainObjectName}(record.id);
    if (res.success) {
      message.success('删除成功');
      // 如果当前页只有一条数据且不是第一页，则跳转到上一页
      if (tableData.value.length === 1 && pagination.current > 1) {
        pagination.current -= 1;
      }
      getTableData();
    } else {
      message.error(res.message || '删除失败');
    }
  } catch (error) {
    console.error('删除出错:', error);
    message.error('删除失败');
  }
};

// 批量删除
const handleBatchDelete = () => {
  if (!selectedRowKeys.value.length) {
    message.warning('请选择要删除的项');
    return;
  }
  
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除选中的 ${selectedRowKeys.value.length} 项吗？此操作不可恢复。`,
    okText: '确认',
    okType: 'danger',
    cancelText: '取消',
    async onOk() {
      try {
        const res = await batchDelete${domainObjectName}(selectedRowKeys.value);
        if (res.success) {
          message.success('批量删除成功');
          selectedRowKeys.value = [];
          getTableData();
        } else {
          message.error(res.message || '批量删除失败');
        }
      } catch (error) {
        console.error('批量删除出错:', error);
        message.error('批量删除失败');
      }
    },
  });
};

<#if specialRequirements?? && specialRequirements?contains("导出")>
// 导出
const handleExport = async () => {
  try {
    message.loading('正在导出，请稍候...', 0);
    const params = prepareSearchParams();
    await export${domainObjectName}Excel(params);
    message.destroy();
    message.success('导出成功');
  } catch (error) {
    message.destroy();
    message.error('导出失败');
  }
};
</#if>

<#if specialRequirements?? && specialRequirements?contains("导入")>
// 导入
const handleImport = async (options) => {
  const { file } = options;
  const formData = new FormData();
  formData.append('file', file);
  
  try {
    message.loading('正在导入，请稍候...', 0);
    const res = await import${domainObjectName}Excel(formData);
    message.destroy();
    
    if (res.success) {
      message.success(`导入成功，成功导入 ${res.data.successCount} 条数据`);
      getTableData();
    } else {
      message.error(res.message || '导入失败');
    }
  } catch (error) {
    message.destroy();
    message.error('导入失败');
  }
};
</#if>

<#list fields as field>
  <#if field.name == "status">
// 获取状态文本
const getStatusText = (status) => {
  const statusMap = {
    0: '禁用',
    1: '启用',
    2: '待审核',
    3: '已拒绝',
    4: '已过期',
  };
  return statusMap[status] || '未知';
};

// 获取状态颜色
const getStatusColor = (status) => {
  const colorMap = {
    0: 'error',
    1: 'success',
    2: 'processing',
    3: 'warning',
    4: 'default',
  };
  return colorMap[status] || 'default';
};
  </#if>
</#list>

// 生命周期钩子
onMounted(() => {
  getTableData();
});
</script>

<style scoped>
.${domainObjectName?uncap_first}-container {
  padding: 24px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.search-container {
  margin-bottom: 16px;
  padding: 16px;
  background-color: #fafafa;
  border-radius: 4px;
}

.operation-container {
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.text-danger {
  color: #ff4d4f;
}
</style> 